<template>
  <m-editor
    ref="editor"
    v-model="value"
    :sidebar="sidebar"
    :menu="menu"
    :runtime-url="runtimeUrl"
    :component-group-list="componentGroup.componentList"
    :props-configs="componentGroup.propsConfigs"
    :props-values="componentGroup.propsValues"
    :stageRect="stageRect"
    :autoScrollIntoView="true"
    :moveableOptions="moveableOptions"
  >
  </m-editor>
</template>

<script lang="ts" setup>
import { ref, createApp, computed, onBeforeMount } from 'vue';
import type StageCore from '@tmagic/stage';
import { editorService } from '@tmagic/editor';
import LcodeAppTree from "./components/LcodeAppTree";
import { Grid, MilkTea, Opportunity, Promotion } from "@element-plus/icons-vue";
import request from "@/request";
import { ElMessage } from 'element-plus';
import { de } from 'element-plus/es/locale';

const editor = ref();

// 应用列表
const appList = ref([]);

// 当前应用
const currentApp = computed(() => {
  const localCurrent = JSON.parse(localStorage.getItem("LCODE_CURRENT_APP") || "{}");
  if (localCurrent && localCurrent.id) {
    return localCurrent;
  } else if (appList.value && appList.value.length) {
    return appList.value[0];
  } else {
    return {};
  }
});

const value = computed(() => {
  return currentApp.value.configs && JSON.parse(currentApp.value.configs) || {
    id: 'app_' + currentApp.value.id,
    name: currentApp.value.name,
    type: 'app',
    items: [],
  };
});

const sidebar = {
  type: 'tabs',
  status: '项目',
  items: [
    {
      type: 'component',
      icon: Grid,
      component: LcodeAppTree,
      text: '项目',
    },
    'component-list',
  ]
};

const menu = {
  left: [
    {
      type: 'button',
      text: '低代码开发平台',
      icon: Promotion
    }
  ],
  center: ['zoom'],
  right: [
    {
      type: 'button',
      text: '保存',
      handler: ({ editorService }) => saveProject(editorService.get('root'))
    },
    {
      type: 'button',
      text: '预览',
      handler: ({ editorService }) => previewProject(editorService.get('page'))
    }
  ],
}

const componentGroup = computed(() => {
  const uiPath = `${currentApp.value.basis || 'vue3'}-ui-${currentApp.value.platform || 'h5'}`;
  let componentList = [];
  let propsConfigs = {};
  let propsValues = {};
  let components: any;

  switch (uiPath) {
    case "vue3-ui-h5":
      components = import.meta.globEager("./../../packages/vue3-ui-h5/**/index.ts");
      break;
    case "vue3-ui-web":
      components = import.meta.globEager("./../../packages/vue3-ui-web/**/index.ts");
      break;
    default:
      components = import.meta.globEager("./../../packages/vue3-ui-h5/**/index.ts");
      break;
  }

  // console.log("uiPath", uiPath)
  // console.log("components", components);
  if (components) {
    const keys = Object.keys(components);
    for (let i = 0; i < keys.length; i++) {
      const infos = keys[i].split("/");
      // console.log(infos);
      const cate = infos[infos.length - 3];
      const name = infos[infos.length - 2];
      const type = currentApp.value.platform + "-" + name;
      const comp = components[keys[i]];

      // componentList
      const hasCate = componentList.find(i => i.title === cate);
      if (hasCate) {
        hasCate.items.push({
          type: type,
          text: name
        })
      } else {
        componentList.push({
          title: cate,
          items: [{
            type: type,
            text: name
          }]
        })
      }

      // propsConfigs
      propsConfigs[type] = comp.config;

      // propsValues
      propsValues[type] = comp.value;
    }
  }

  // console.log("componentList", componentList)
  // console.log("propsConfigs", propsConfigs)
  // console.log("propsValues", propsValues)
  return {
    componentList,
    propsConfigs,
    propsValues
  }
});

const runtimeUrl = 'http://localhost:8078/';

const stageRect = computed(() => {
  if (currentApp.value.platform === "web") {
    return {
      width: 1024,
      height: 688
    }
  } else if (currentApp.value.platform === "h5") {
    return {
      width: 375,
      height: 667
    }
  }
});

const moveableOptions = (core?: any) => {
  const options = {};
  const id = core?.dr?.target?.id;

  if (!id || !editor.value) return options;

  const node = editor.value.editorService.getNodeById(id);

  if (!node) return options;

  const isPage = node.type === "page";

  // 非页面才能拖拽
  options.draggable = !isPage;
  options.resizable = !isPage;

  return options;
}

// fix layout
const key = "$MagicEditorColumnWidthData";
const EditorColumnWidthData = JSON.parse(localStorage.getItem(key) || "{}");
localStorage.setItem(key, JSON.stringify(Object.assign(EditorColumnWidthData, {
  right: "260"
})));

// 获取项目列表
const getProjects = async () => {
  const res = await request.request({
    url: "/api/project/list",
    method: "get",
    params: {
      size: 1000
    }
  });
  // console.log("res", res);
  if (res && res.list && res.list.length) {
    appList.value = res.list;
    localStorage.setItem("LCODE_APP_LIST", JSON.stringify(appList.value));
    const localCurrent = JSON.parse(localStorage.getItem("LCODE_CURRENT_APP") || "{}");
    if (!localCurrent || !localCurrent.id) {
      localStorage.setItem("LCODE_CURRENT_APP", JSON.stringify(appList.value[0]));
    }
  }
};

// 保存项目
const saveProject = async (configs) => {
  // const configs = computed(() => editorService.get('root'));
  const localCurrent = JSON.parse(localStorage.getItem("LCODE_CURRENT_APP") || "{}");
  const data = Object.assign({}, localCurrent, {
    configs: JSON.stringify(configs)
    // configs: configs
  });
  localStorage.setItem("LCODE_CURRENT_APP", JSON.stringify(data));
  const res = await request.request({
    url: "/api/project/update",
    method: "post",
    params: {
      id: localCurrent.id
    },
    data: {
      configs: configs && JSON.stringify(configs)
    }
  });
  if (res && res.id) {
    ElMessage.success("保存成功");
  }
};

// 预览项目
const previewProject = async (page) => {
  const localCurrent = JSON.parse(localStorage.getItem("LCODE_CURRENT_APP") || "{}");
  window.open(`${runtimeUrl}?localPreview=1&project=${localCurrent.id}&page=${page && page.id}`);
};

onBeforeMount(async () => {
  await getProjects();
});
</script>

<style>
html,
body,
#app,
.m-editor {
  height: 100vh;
}

body {
  margin: 0;
}

#app {
  overflow: auto;
}

html,body,#app {
  height: 100%; margin: 0;padding: 0;
}

#app::-webkit-scrollbar {
  width: 0 !important;
  display: none;
}
</style>
